package com.template.Interceptor;

import cn.hutool.jwt.Claims;
import com.alibaba.excel.util.StringUtils;
import com.template.properties.JwtProperties;
import com.template.utils.JwtUtils;
import com.template.context.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

//import static org.codehaus.jettison.json.JSONObject.*;

/**
 * 登录检查
 * 1.配置到拦截器要拦截哪些请求
 * 2.把这些配置放在容器中
 *
 * 实现HandlerInterceptor接口
 */
@Slf4j
@Component
//https://blog.csdn.net/heihaozi/article/details/131428958
public class LoginInterceptor implements HandlerInterceptor {



//    @Autowired
//    private JwtUtils jwtUtils;
    @Autowired
    private JwtProperties jwtProperties;

    private static ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

//    HttpServletRequest request: HTTP请求对象，用于获取请求信息。
//    HttpServletResponse response: HTTP响应对象，用于设置响应信息。
//    Object handler: 控制器方法的处理器对象，通常不需要使用此参数


//    preHandle：在请求到达处理器之前执行，可以用于权限验证、数据校验等操作。如果返回true，则继续执行后续操作；如果返回false，则中断请求处理。
    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
        // 获取进过拦截器的路径
        String url = req.getRequestURI();
//        System.out.println(url+"获取进过拦截器的路径");

        //判断当前拦截到的是Controller的方法还是其他资源
        if (!(handler instanceof HandlerMethod)) {
            //当前拦截到的不是动态方法，直接放行
            return true;
        }

        // 登录检查逻辑
        String jwt=req.getHeader("Authorization");

        String key="MuErZhi";

//
//        //判断令牌是否存在
        if(StringUtils.isEmpty(jwt)){
            log.info("请求头token为空,返回未登录的信息");
//            Result error= Result.error("请先登录");
//            ObjectMapper mapper = new ObjectMapper();
//            String noLogin= mapper.writeValueAsString(error);
//            resp.getWriter().write(noLogin);
//            System.out.println("sss"+noLogin);
//            UserContextHolder.clear();
            resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);//返回响应码401
            return false;
        }else{
//            /判断令牌是否过期
            boolean isExpired= JwtUtils.isJwtExpired(jwt,key);
//            System.out.println("jwt是否过期"+isExpired);
            if(isExpired){
                log.info("登录过期");
//                Result error= Result.error("登录已过期,请重新登录");
//                ObjectMapper mapper = new ObjectMapper();
//                String noLogin= mapper.writeValueAsString(error);
//                resp.getWriter().write(noLogin);
//                System.out.println(noLogin);
//                UserContextHolder.clear();
                resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);//返回响应码401

                System.out.println("移除当前登录id"+UserContext.getCurrentUserId());
                UserContext.removeCurrentUserId();

                return false;
            }
        }

//        System.out.println("传入的jwt"+jwt);
        Map<String,Object> claims=JwtUtils.parseJWT(jwt);
        Integer userId= (Integer) claims.get("id");

        UserContext.setCurrentUserId(Long.valueOf(userId));
        System.out.println("拦截器存入"+UserContext.getCurrentUserId());


        return true;
    }

//    postHandle：在处理器处理请求之后执行，可以用于日志记录、缓存处理等操作。
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

//    afterCompletion：在视图渲染之后执行，可以用于资源清理等操作。
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}



